package org.hard.util;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSON;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.Getter;
import lombok.Setter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.*;

/**
 * @author: 王林博
 * @date: 2023年01月12日 11:37
 */
public class LuckyDrawUtil {

    private static Logger logger = LoggerFactory.getLogger(LuckyDrawUtil.class);
    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    public static String obj2Str(Object object) throws JsonProcessingException {
        return OBJECT_MAPPER.writeValueAsString(object);
    }

    @Setter
    @Getter
    public static class Entity {

        public Entity(Integer id,Integer ratio, String name) {
            this.id = id;
            this.ratio = ratio;
            this.name = name;
        }

        private Integer id;
        private Integer ratio;


        private String name;
    }


    public static void main(String[] args) throws JsonProcessingException {
        List<Entity> prizeList = new ArrayList<>();
        final Entity entity = new Entity(1, 1, "10彩虹豆");
        prizeList.add(entity);

        final Map<String, Object> map = BeanUtil.beanToMap(entity);

        Map<String,Object> data = new HashMap<>(5);
        data.put("businessID","custom_message_liaoType");
        data.put("customMessageJson", map);

        Map<String,String> push = new HashMap<>(5);

        push.put("data",JSONUtil.toJsonStr(data));

        System.out.println(JSONUtil.toJsonStr(push));

        logger.error(DateUtil.format(DateUtil.date(1676127600*1000L), "yyyy-MM-dd HH:mm:ss"));
//        logger.error( String.valueOf(JSONUtil.parse(s)));
//        logger.error(obj2Str(JacksonUtil.readValue(s,String)));
        // 获取奖品信息列表
//        List<Entity> prizeList = new ArrayList<>();
//
//        /**
//         * 5
//         * 3
//         * 2
//         * 1
//         * 50
//         * 20
//         * 12
//         * 7
//         */
//        prizeList.add(new Entity(1,1,"10彩虹豆"));
//        prizeList.add(new Entity(2,2,"28无门槛"));
//        prizeList.add(new Entity(3,3,"满88减58"));
//        prizeList.add(new Entity(4,5,"满88减38"));
//        prizeList.add(new Entity(5,7,"50成长值"));
//        prizeList.add(new Entity(6,12,"30成长值"));
//        prizeList.add(new Entity(7,20,"20成长值"));
//        prizeList.add(new Entity(8,50,"10成长值"));
//
//        prizeList.sort(Comparator.comparingDouble(Entity::getRatio));
//        Integer sum = 0;
//        List<Entity> newList = new ArrayList<>();
//        for (int i = 0; i < prizeList.size(); i++) {
//            Entity entityItem = prizeList.get(i);
//
//            sum = sum + (entityItem.getRatio());
//            newList.add(new Entity(entityItem.getId(), sum, entityItem.getName()));
//        }
//        List<Entity> prizes = new ArrayList<>();
//        List<Entity> prizeItem = new ArrayList<>();
//        for (int i = 0; i < 1000000; i++) {
//            prizes.add(tet(newList));
//            prizeItem.add(lottery(newList));
//        }
//
//        Map<String, List<Entity>> collect = prizes.stream().collect(Collectors.groupingBy(Entity::getName));
//        collect.forEach((k, v) -> System.out.println(k + " 被抽中 " + v.size() + " 次"));
//        System.out.println();
//        Map<String, List<Entity>> collectList = prizeItem.stream().collect(Collectors.groupingBy(Entity::getName));
//        collectList.forEach((k, v) -> System.out.println(k + " 被抽中 " + v.size() + " 次"));
    }

    public static Entity tet(List<Entity> newList) {


// 奖品列表中的概率为累加概率
// 需要按照添加进列表的顺序进行累加，为了数据处理方便中奖几率*100
// 个人感觉更精确

// 生成一个随机数
        Random random = new Random();
        Double userSelect = random.nextDouble() * 100;
//        System.out.println(userSelect);
        for (Entity prize : newList) {
            // 随机数小于中奖几率，则中奖
            if (userSelect < prize.getRatio()) {
                return prize;
            }
        }
        return new Entity(100,10000,"异常");
// 谢谢参与
//        List<Entity> prize = prizeList.stream().filter(item -> item.getPrizeType() == 6).collect(Collectors.toList());
//        if (prize.size() > 0) {
//            System.out.println(prize.get(0).getName());
////            return prize.get(0);
//        }
//        return null;

    }

    public static Entity lottery(List<Entity> prizeList) {
        //按照权重从小到大排序奖品
        prizeList.sort(Comparator.comparingDouble(Entity::getRatio));

        //计算节点 节点的数量比奖品的数量多一个，即0
        List<Integer> nodeList = new ArrayList<>();
        //第一个节点为0
        nodeList.add(0);
        for (Entity prize : prizeList) {
            //每一个节点等于前一个节点+当前奖品的权重
            nodeList.add(nodeList.get(nodeList.size() - 1) + prize.getRatio());
        }

        //生成 0-结束节点 的随机数
        int randomInt = RandomUtil.randomInt(0, nodeList.get(nodeList.size() - 1));

        //最终抽奖逻辑 此处需要从第二个节点开始遍历
        for (int i = 1; i < nodeList.size(); i++) {
            //本次节点
            Integer endNode = nodeList.get(i);
            //前一个节点
            Integer startNode = nodeList.get(i - 1);
            //若随机数大于等于前一个节点并且小于本节点，在prizeList中位于i-1位置的奖品为抽中奖品
            //Tip：比较大小时，左闭右开与左开右闭都可以，不影响整体概率
            if (randomInt >= startNode
                    && randomInt < endNode) {
                return prizeList.get(i - 1);
            }
        }
        throw new RuntimeException("程序异常 生成的随机数不在任何奖品区间内");
    }

}
